package j_util.database;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * This class provides a concrrency control, establishing
 */
public class ConcurrencyAdministrator {
    public Map<String, ExecutorService> connectionThreads = new HashMap<String, ExecutorService>();
    private static long awaitTermination = 5;

    public void setThreads(String connectionURL, int threads) {
        if (connectionThreads.containsKey(connectionURL)) {
            try {
                connectionThreads.get(connectionURL).awaitTermination(awaitTermination, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            connectionThreads.put(connectionURL, Executors.newFixedThreadPool(threads));
        }
    }

    public void executeOperation(String connectionURL, Runnable operation) {
        if (!connectionThreads.containsKey(connectionURL)) {
            connectionThreads.put(connectionURL, Executors.newFixedThreadPool(20));
        }
        connectionThreads.get(connectionURL).execute(operation);
    }

    public long getAwaitTermination() {
        return awaitTermination;
    }

    /**
     * Provides turns awaitTermination value to the specified, in order to consider it at setThreads method while the
     * requested connection already exists. Is used to avoid abrupt interrupt at DB operations. The value is considered
     * only if the time requested is smaller than the currently considered;
     *
     * @param awaitTermination - time to be considered at setThreads method;
     */
    public static void setAwaitTermination(long awaitTermination) {
        if (ConcurrencyAdministrator.awaitTermination < awaitTermination) {
            ConcurrencyAdministrator.awaitTermination = awaitTermination;
        }
    }
}
